package global

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/fatih/color"

	"gitee.com/csingo/csingo/command"
)

type CommandContainer struct {
	Instances    map[string]command.CommandInterface
	MethodParams map[string][]string
}

func (c *CommandContainer) Inject(instance command.CommandInterface) {
	desc := instance.Desc()
	c.Instances[desc.Name] = instance
	for _, method := range desc.Methods {
		key := fmt.Sprintf("%s::%s", desc.Name, method.Name)
		c.MethodParams[key] = []string{}
		for _, param := range method.Params {
			c.MethodParams[key] = append(c.MethodParams[key], param.Name)
		}
	}
	command.Instances = append(command.Instances, instance)
}

func (c *CommandContainer) Run(cmd, method string, params map[string]string) {
	// 判断指令是否存在
	if _, ok := c.Instances[cmd]; !ok {
		color.Set(color.FgHiRed)
		fmt.Printf("指令【%s::%s】不存在! 请使用【help】获取帮助 或者 使用【version::update】更新工具.\n", cmd, method)
		color.Set(color.FgWhite)
		return
	}

	instance := c.Instances[cmd]
	methodName := strings.Title(method)

	// 判断指令方法是否存在
	_, exists := reflect.TypeOf(instance).MethodByName(methodName)
	if !exists {
		color.Set(color.FgHiRed)
		fmt.Printf("指令【%s::%s】方法错误! 请使用【help】获取帮助 或者 使用【version::update】更新工具.\n", cmd, method)
		color.Set(color.FgWhite)
		return
	}

	mk := fmt.Sprintf("%s::%s", cmd, method)
	var callParams []reflect.Value
	for _, name := range c.MethodParams[mk] {
		if _, ok := params[name]; ok {
			callParams = append(callParams, reflect.ValueOf(params[name]))
		} else {
			callParams = append(callParams, reflect.ValueOf(""))
		}
	}

	m := reflect.ValueOf(instance).MethodByName(methodName)
	m.Call(callParams)
}
